﻿///////////////////////////////////////////////////////////////////////////////
//
// This file is part of the BassDrop project
//   https://code.google.com/p/bass-drop/
//
//
// Creator:	Gergely Krajcsovszki (krajcsovszkig@hotmail.com)
// Date:	2013-08-26 12:30
//
//
// Copyright © 2013-2014. Gergely Krajcsovszki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
///////////////////////////////////////////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using BassDrop.Core.Common.Media.Playlists;
using BassDrop.Core.Common;
using BassDrop.Core.Common.Media.Library;
using BassDrop.DesktopClient.UI.Panels;
using BassDrop.DesktopClient.UI.Dialogs;
using BassDrop.Core.Common.Localization;
using BassDrop.DesktopClient.Utilities;
using System.Collections;

namespace BassDrop.DesktopClient.UI.Views
{
	/// <summary>
	/// View / page for showing the saved playlists
	/// </summary>
	public partial class PlaylistsView : ContentViewBase
	{
		public PlaylistsView()
		{
			InitializeComponent();

			Library.Instance.Playlists.CollectionChanged += Playlists_CollectionChanged;

			LayoutPlaylists();
		}

		private void LayoutPlaylists()
		{
			ListViewPlaylists.Items.Clear();

			lock ( ((ICollection) Library.Instance.Playlists).SyncRoot )
			{
				foreach ( var playlist in Library.Instance.Playlists )
				{
					ListViewItem playlistItem = new ListViewItem();
					playlistItem.Content = playlist.Name;

					PlaylistPanel playlistPanel = new PlaylistPanel();
					playlistPanel.Playlist = playlist;
					playlistPanel.Ordered = true;

					playlistItem.Selected += ( sender, e ) =>
					{
						PlaylistPanelGrid.Children.Clear();
						PlaylistPanelGrid.Children.Add( playlistPanel );
					};

					playlistItem.MouseDoubleClick += ( sender, e ) =>
					{
						playlistPanel.PlayFromStart();
					};

					ListViewPlaylists.Items.Add( playlistItem );
				}
			}
		}

		private void Playlists_CollectionChanged( object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e )
		{
			LayoutPlaylists(); // TODO: hatékonyabban
		}

		private void ButtonNewPlaylist_Click( object sender, RoutedEventArgs e )
		{
			string name;

			if ( InputDialog.ShowDialog( App.Instance.MainWindow, Strings.LabelPlaylistCreationNameInputDescription, Strings.LabelPlaylistCreationNameInputCaption, out name ) == true )
			{
				Library.Instance.Playlists.Add( new Playlist( name ) );
			}
		}

		private void ListViewPlaylists_PreviewKeyDown( object sender, KeyEventArgs e )
		{
			switch ( e.Key )
			{
				case Key.Delete:
					{
						List<Playlist> toRemove = new List<Playlist>();

						foreach ( var item in ListViewPlaylists.SelectedItems )
						{
							toRemove.Add( Library.Instance.Playlists[ListViewPlaylists.Items.IndexOf( item )] );
						}

						if ( toRemove.Count > 0 )
						{
							Library.Instance.Playlists.RemoveRange( toRemove );
						}

						e.Handled = true;
					}
					break;

				case Key.Enter:
					{
						if ( ListViewPlaylists.SelectedIndex >= 0 )
						{
							Controller.Instance.NowPlaying.SyncFrom( Library.Instance.Playlists[ListViewPlaylists.SelectedIndex] );
							Controller.Instance.NowPlaying.SelectedIndex = 0;
							Controller.Instance.NowPlaying.Play();
						}

						e.Handled = true;
					}
					break;
			}
		}

		#region Row reordering via drag-drop

		// Based on http://www.hardcodet.net/2009/03/moving-data-grid-rows-using-drag-and-drop

		/// <summary>
		/// Keeps in mind whether the rows are currently being dragged
		/// </summary>
		private bool IsDragging
		{
			get;
			set;
		}

		/// <summary>
		/// The item currently being dragged
		/// </summary>
		public Playlist DraggedItem
		{
			get;
			set;
		}

		private void ListViewPlaylists_PreviewMouseLeftButtonDown( object sender, MouseButtonEventArgs e )
		{
			//exit if in edit mode
			if ( IsDragging )
			{
				return;
			}

			//find the clicked row
			var item = ((UIElement) sender).TryFindFromPoint<ListViewItem>( e.GetPosition( ListViewPlaylists ) );
			if ( item == null )
			{
				return;
			}

			//set flag that indicates we're capturing mouse movements
			IsDragging = true;
			DraggedItem = Library.Instance.Playlists[ListViewPlaylists.Items.IndexOf( item )];
		}

		private void ListViewPlaylists_MouseLeftButtonUp( object sender, MouseButtonEventArgs e )
		{
			//reset
			ResetDragDrop();
		}

		private void ListViewPlaylists_MouseMove( object sender, MouseEventArgs e )
		{
			if ( !IsDragging || e.LeftButton != MouseButtonState.Pressed )
			{
				ResetDragDrop();
				return;
			}

			Point position = e.GetPosition( ListViewPlaylists );
			var item = ListViewPlaylists.TryFindFromPoint<ListViewItem>( position );
			if ( item != null )
			{
				//get the target item
				Playlist targetItem = Library.Instance.Playlists[ListViewPlaylists.Items.IndexOf( item )];

				if ( targetItem == null || !ReferenceEquals( DraggedItem, targetItem ) )
				{
					int draggedIndex = Library.Instance.Playlists.IndexOf( DraggedItem );
					int targetIndex = Library.Instance.Playlists.IndexOf( targetItem );
					Library.Instance.Playlists.Move( draggedIndex, targetIndex );
				}
			}
		}

		/// <summary>
		/// Closes the popup and resets the
		/// grid to read-enabled mode.
		/// </summary>
		private void ResetDragDrop()
		{
			IsDragging = false;
			DraggedItem = null;
		}

		#endregion Row reordering via drag-drop
	}
}
